package org.mozhu.mboot.admin.config;

import org.mozhu.mboot.admin.security.CustomUserDetailsService;
import org.mozhu.mboot.core.web.security.HttpSecurityHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
import org.springframework.session.security.SpringSessionBackedSessionRegistry;
import org.springframework.social.security.SpringSocialConfigurer;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    SpringSocialConfigurer springSocialConfigurer;

    @Autowired
    FindByIndexNameSessionRepository<? extends Session> sessionRepository;

    @Bean
    public CustomUserDetailsService customUserDetailsService() {
        return new CustomUserDetailsService();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService()).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        HttpSecurityHolder.get().setHttpSecurity(http);

        //所有静态资源，开发页面，错误页面任意访问
        http.authorizeRequests()
                .antMatchers("/dev/**").permitAll()
                .antMatchers("/error").permitAll()
                .antMatchers(WebConfiguration.STATIC_RESOURCE_PATTERNS.toArray(new String[0])).permitAll();

        // 登录
        http.authorizeRequests()
                .anyRequest().authenticated() //任何请求,登录后可以访问
                .and()
                .headers().frameOptions().disable()
                .and()
                .csrf().disable()
                .formLogin()
                .loginPage("/login").permitAll() //登录页面用户任意访问
                .and()
                .rememberMe().key("111")
                .and()
                .logout().permitAll(); //注销行为任意访问

        // 第三方账号授权登录
        http.authorizeRequests()
                .antMatchers("/social/**").permitAll()
                .and()
                .apply(springSocialConfigurer);

        // spring-session 支持并发登录控制
        http.sessionManagement()
                .maximumSessions(2)
                .sessionRegistry(sessionRegistry());

    }

    @Bean
    public SpringSessionBackedSessionRegistry sessionRegistry() {
        return new SpringSessionBackedSessionRegistry<>(this.sessionRepository);
    }
}
